package com.isunland.managesystem.common;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Tools for handler picture
 *
 * @author Ryan.Tang
 */
public final class ImageTools {

  /**
   * Transfer drawable to bitmap
   */
  public static Bitmap drawableToBitmap(Drawable drawable) {
    int w = drawable.getIntrinsicWidth();
    int h = drawable.getIntrinsicHeight();

    Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
        : Bitmap.Config.RGB_565;
    Bitmap bitmap = Bitmap.createBitmap(w, h, config);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, w, h);
    drawable.draw(canvas);
    return bitmap;
  }

  /**
   * Bitmap to drawable
   */
  public static Drawable bitmapToDrawable(Bitmap bitmap) {
    return new BitmapDrawable(bitmap);
  }

  /**
   * Input stream to bitmap
   *
   * @throws Exception
   */
  public static Bitmap inputStreamToBitmap(InputStream inputStream) throws Exception {
    return BitmapFactory.decodeStream(inputStream);
  }

  /**
   * Byte transfer to bitmap
   */
  public static Bitmap byteToBitmap(byte[] byteArray) {
    if (byteArray.length != 0) {
      return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    } else {
      return null;
    }
  }

  /**
   * Byte transfer to drawable
   */
  public static Drawable byteToDrawable(byte[] byteArray) {
    ByteArrayInputStream ins = null;
    if (byteArray != null) {
      ins = new ByteArrayInputStream(byteArray);
    }
    return Drawable.createFromStream(ins, null);
  }

  /**
   * Bitmap transfer to bytes
   */
  public static byte[] bitmapToBytes(Bitmap bm) {
    byte[] bytes = null;
    if (bm != null) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
      bytes = baos.toByteArray();
    }
    return bytes;
  }

  /**
   * Drawable transfer to bytes
   */
  public static byte[] drawableToBytes(Drawable drawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();
    byte[] bytes = bitmapToBytes(bitmap);
    ;
    return bytes;
  }

  /**
   * Base64 to byte[] //
   */
  // public static byte[] base64ToBytes(String base64) throws IOException {
  // byte[] bytes = Base64.decode(base64);
  // return bytes;
  // }
  //
  // /**
  // * Byte[] to base64
  // */
  // public static String bytesTobase64(byte[] bytes) {
  // String base64 = Base64.encode(bytes);
  // return base64;
  // }

  /**
   * Create reflection images
   */
  public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
    final int reflectionGap = 4;
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();

    Matrix matrix = new Matrix();
    matrix.preScale(1, -1);

    Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, h / 2, w, h / 2, matrix, false);

    Bitmap bitmapWithReflection = Bitmap.createBitmap(w, (h + h / 2), Config.ARGB_8888);

    Canvas canvas = new Canvas(bitmapWithReflection);
    canvas.drawBitmap(bitmap, 0, 0, null);
    Paint deafalutPaint = new Paint();
    canvas.drawRect(0, h, w, h + reflectionGap, deafalutPaint);

    canvas.drawBitmap(reflectionImage, 0, h + reflectionGap, null);

    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
        bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
    paint.setShader(shader);
    // Set the Transfer mode to be porter duff and destination in
    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
    // Draw a rectangle using the paint with our linear gradient
    canvas.drawRect(0, h, w, bitmapWithReflection.getHeight() + reflectionGap, paint);

    return bitmapWithReflection;
  }

  /**
   * Get rounded corner images
   *
   * @param roundPx 5 10
   */
  public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, w, h);
    final RectF rectF = new RectF(rect);
    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
  }

  /**
   * Resize the bitmap
   */
  public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Matrix matrix = new Matrix();
    float scaleWidth = ((float) width / w);
    float scaleHeight = ((float) height / h);
    matrix.postScale(scaleWidth, scaleHeight);
    Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
    return newbmp;
  }

  /**
   * Resize the drawable
   */
  public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
    int width = drawable.getIntrinsicWidth();
    int height = drawable.getIntrinsicHeight();
    Bitmap oldbmp = drawableToBitmap(drawable);
    Matrix matrix = new Matrix();
    float sx = ((float) w / width);
    float sy = ((float) h / height);
    matrix.postScale(sx, sy);
    Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
    return new BitmapDrawable(newbmp);
  }

  /**
   * Get images from SD card by path and the name of image
   */
  public static Bitmap getPhotoFromSDCard(String path, String photoName) {
    Bitmap photoBitmap = BitmapFactory.decodeFile(path + "/" + photoName + ".png");
    if (photoBitmap == null) {
      return null;
    } else {
      return photoBitmap;
    }
  }

  /**
   * Check the SD card
   */
  public static boolean checkSDCardAvailable() {
    return android.os.Environment.getExternalStorageState()
        .equals(android.os.Environment.MEDIA_MOUNTED);
  }

  /**
   * Get image from SD card by path and the name of image
   */
  public static boolean findPhotoFromSDCard(String path, String photoName) {
    boolean flag = false;

    if (checkSDCardAvailable()) {
      File dir = new File(path);
      if (dir.exists()) {
        File folders = new File(path);
        File photoFile[] = folders.listFiles();
        for (int i = 0; i < photoFile.length; i++) {
          String fileName = photoFile[i].getName().split("\\.")[0];
          if (fileName.equals(photoName)) {
            flag = true;
          }
        }
      } else {
        flag = false;
      }
      // File file = new File(path + "/" + photoName + ".jpg" );
      // if (file.exists()) {
      // flag = true;
      // }else {
      // flag = false;
      // }

    } else {
      flag = false;
    }
    return flag;
  }

  /**
   * Save image to the SD card
   */
  public static File savePhotoToSDCard(Bitmap photoBitmap, String path, String photoName) {
    if (!checkSDCardAvailable()) {

      return null;
    }

    File dir = new File(path);
    if (!dir.exists()) {
      dir.mkdirs();
    }

    File photoFile = new File(path, photoName + ".png");
    FileOutputStream fileOutputStream = null;
    try {
      fileOutputStream = new FileOutputStream(photoFile);
      if (photoBitmap != null) {
        if (photoBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)) {
          fileOutputStream.flush();
        }
      }
    } catch (Exception e) {
      photoFile.delete();
      e.printStackTrace();
    } finally {
      try {
        if (fileOutputStream != null) {
          fileOutputStream.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return photoFile;
  }

  /**
   * Delete the image from SD card
   *
   * @param path file:///sdcard/temp.jpg
   */
  public static void deleteAllPhoto(String path) {
    if (checkSDCardAvailable()) {
      File folder = new File(path);
      File[] files = folder.listFiles();
      for (int i = 0; i < files.length; i++) {
        files[i].delete();
      }
    }
  }

  public static void deletePhotoAtPathAndName(String path, String fileName) {
    if (checkSDCardAvailable()) {
      File folder = new File(path);
      File[] files = folder.listFiles();
      for (int i = 0; i < files.length; i++) {
        if (files[i].getName().split("\\.")[0].equals(fileName)) {
          files[i].delete();
        }
      }
    }
  }
}
